package com.sgl.gk.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.collection.CollUtil;
import com.sgl.common.annotation.Log;
import com.sgl.common.core.domain.AjaxResult;
import com.sgl.common.enums.BusinessType;
import com.sgl.common.utils.StringUtils;
import com.sgl.common.utils.poi.ExcelUtil;
import com.sgl.gk.controller.vo.*;
import com.sgl.gk.domain.GkStation;
import com.sgl.gk.domain.GkStationConfiguration;
import com.sgl.gk.mapper.GkProductionLineMapper;
import com.sgl.gk.mapper.GkStationMapper;
import com.sgl.gk.service.GkStationConfigurationService;
import com.sgl.gk.service.impl.GkStationConfigurationServiceImpl;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author:xec
 * @date:2022/10/31 18:50
 *
 * 工位配置表的controller
 **/
@Controller
@RequestMapping("/gk/stationconfiguration")
public class GkStationConfigurationController {

    @Autowired
    GkStationConfigurationService gkStationConfigurationService;

    @Autowired
    GkStationMapper gkStationMapper;

    @Autowired
    GkProductionLineMapper gkProductionLineMapper;

    /**
     * 查询工位变量
     * @param gkStationConfiguration
     * @return
     */
    @GetMapping("/list")
    @ResponseBody
    public AjaxResult list(GkStationConfiguration gkStationConfiguration){
        if (gkStationConfiguration.getStationId()==null||gkStationConfiguration.getType()==null){
            return AjaxResult.error("工位id和配置类型字段验证不通过");
        }
        Map<String,Object> map = new HashMap<>();
        List<GkStationConfigurationVo> list = gkStationConfigurationService.list(gkStationConfiguration);
        if (list.size()>0) {
            List<Integer> collect = list.stream().map(a -> a.getVariableIndex()==null?0:a.getVariableIndex()).collect(Collectors.toList());

            Integer max = Collections.max(collect);
            Integer min = Collections.min(collect);
            map.put("max", max);
            map.put("min", min);
            map.put("total", list.size());
            map.put("namespaces", (list.get(0) == null ? 0 : list.get(0).getNameSpaces() == null ? 0 : list.get(0).getNameSpaces()));
            map.put("GkStationConfigurationList", list);
        }
        return AjaxResult.success(map);
    }

    @GetMapping("/listByProductLineId")
    @ResponseBody
    public AjaxResult listByProductLineId(Long productLineId){
        return gkStationConfigurationService.listByProductLineId(productLineId);
    }

    /**
     * 添加工位变量
     * @param gkStationConfiguration
     * @return
     */
    @PostMapping("/add")
    @ResponseBody
    @Log(title = "工位配置",businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody GkStationConfiguration gkStationConfiguration){
        if (gkStationConfiguration.getStationId() == null || gkStationConfiguration.getType() == null) {
            return AjaxResult.error("工位类型和配置类型必须传");
        }
        if (gkStationConfiguration.getVariableIndex() == null|| StringUtils.isEmpty(gkStationConfiguration.getDataType())||StringUtils.isEmpty(gkStationConfiguration.getVariableName())
                ||StringUtils.isEmpty(gkStationConfiguration.getDisplayName())){
            return AjaxResult.error("排序号、显示名称、数据类型、变量名称必需字段验证未通过");
        }
        if (gkStationConfiguration.getCheckLength()!=null&&gkStationConfiguration.getCheckLength()>127) {
            return AjaxResult.error("检验长度超出范围");
        }
        if (gkStationConfiguration.getVariableAddress()!=null&&gkStationConfiguration.getVariableAddress()>2147483647){
            return AjaxResult.error("变量地址超出范围");
        }
        if (StringUtils.length(gkStationConfiguration.getDisplayName())>100) {
            return AjaxResult.error("显示名称长度不能超出100个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableName())>100){
            return AjaxResult.error("变量名称长度不能超出100个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableComments())>250) {
            return AjaxResult.error("变量注释长度不能超出250个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableRemarks())>250) {
            return AjaxResult.error("变量备注长度不能超过250个字符");
        }
        if (gkStationConfiguration.getCheckLength() != null&&gkStationConfiguration.getCheckLength()!=0&&!gkStationConfiguration.getDataType().equals("boolean")) {
            if (gkStationConfiguration.getCheckLength()!=null&&gkStationConfiguration.getDefaultValue()!=null&&gkStationConfiguration.getDefaultValue().length()>gkStationConfiguration.getCheckLength()){
                return AjaxResult.error("默认值长度不能大于"+gkStationConfiguration.getCheckLength());
            }
        }
        int row = gkStationConfigurationService.add(gkStationConfiguration);
        if (row>0) {
            return AjaxResult.success("插入成功");
        }
        return AjaxResult.error("插入失败");
    }

    /**
     * 修改工位变量
     * @param gkStationConfiguration
     * @return
     */
    @PutMapping("/edit")
    @ResponseBody
    @Log(title = "工位配置",businessType = BusinessType.UPDATE)
    public AjaxResult edit(@RequestBody GkStationConfiguration gkStationConfiguration){
        if (gkStationConfiguration.getStationId() == null || gkStationConfiguration.getType() == null) {
            return AjaxResult.error("工位类型和配置类型必须传");
        }
        if (gkStationConfiguration.getVariableIndex() == null|| StringUtils.isEmpty(gkStationConfiguration.getDataType())||
                StringUtils.isEmpty(gkStationConfiguration.getVariableName()) ||StringUtils.isEmpty(gkStationConfiguration.getDisplayName())){
            return AjaxResult.error("排序号、显示名称、数据类型、变量名称和所属空间必需字段验证未通过");
        }
        if (gkStationConfiguration.getCheckLength()!=null&&gkStationConfiguration.getCheckLength()>127) {
            return AjaxResult.error("检验长度超出范围");
        }
        if (gkStationConfiguration.getVariableAddress()!=null&&gkStationConfiguration.getVariableAddress()>2147483647){
            return AjaxResult.error("变量地址超出范围");
        }
        if (StringUtils.length(gkStationConfiguration.getDisplayName())>100) {
            return AjaxResult.error("显示名称长度不能超出100个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableName())>100){
            return AjaxResult.error("变量名称长度不能超出100个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableComments())>250) {
            return AjaxResult.error("变量注释长度不能超出250个字符");
        }
        if (StringUtils.length(gkStationConfiguration.getVariableRemarks())>250) {
            return AjaxResult.error("变量备注长度不能超过250个字符");
        }
        if (gkStationConfiguration.getCheckLength() != null&&gkStationConfiguration.getCheckLength()!=0&&!gkStationConfiguration.getDataType().equals("boolean")) {
            if (gkStationConfiguration.getCheckLength()!=null&&gkStationConfiguration.getDefaultValue()!=null&&gkStationConfiguration.getDefaultValue().length()>gkStationConfiguration.getCheckLength()){
                return AjaxResult.error("默认值长度不能大于"+gkStationConfiguration.getCheckLength());
            }
        }
        return gkStationConfigurationService.edit(gkStationConfiguration);
    }

    /**
     * 保存按钮接口
     * @param gkStationConfigurations
     * @return
     */
    @PostMapping("/editList")
    @Log(title = "工位配置",businessType = BusinessType.UPDATE)
    @ResponseBody
    public AjaxResult editList(@RequestBody  GkStationConfiguration[] gkStationConfigurations){
        return gkStationConfigurationService.editList(gkStationConfigurations);
    }

    /**
     * 工位配置变量删除接口
     * @param ids
     * @return
     */
    @DeleteMapping("/{ids}")
    @ResponseBody
    @Log(title = "工位配置",businessType = BusinessType.DELETE)
    public AjaxResult removeByIds(@PathVariable("ids") Long[] ids){
        return gkStationConfigurationService.removeByIds(ids);
    }



    /**
     * 整个产品的返修记录
     * @param barCode
     * @return
     */
//    @GetMapping("/repairRecord")
    @ResponseBody
    public AjaxResult repairRecord(String barCode){
        List<GkSparePartsVo> gkSparePartsVos = gkStationConfigurationService.repairRecord(barCode);
        return AjaxResult.success(gkSparePartsVos);
    }

    /**
     * 整个产品的返修记录导出返修记录
     * @param barCode
     * @return
     */
    @GetMapping("/exportRepairRecord")
    @ResponseBody
    @Log(title = "工位配置",businessType = BusinessType.EXPORT)
    public void exportRepairRecord(String barCode, HttpServletResponse response, HttpServletRequest request){
        gkStationConfigurationService.exportRepairRecord(barCode,response,request);
    }

    /**
     * 设置按钮接口
     * @param gkStationConfigurations
     * @return
     */
    @PostMapping("/setParameters")
    @ResponseBody
    public AjaxResult setParameters(@RequestBody SaveTemplateVo saveTemplateVo){
        // 与opcua后端通讯
        List<GkStationConfiguration> gkStationConfigurations = saveTemplateVo.getGkStationConfigurations();
        return gkStationConfigurationService.setParameters(gkStationConfigurations.toArray(new GkStationConfiguration[0]),saveTemplateVo.getTemplateId());
    }

    /**
     * 导出配置参数
     * @param exportParamConfigVoList
     * @param response
     */
    @PostMapping("/exportParamConfig")
    public void exportParamConfig(@RequestBody List<ExportParamConfigVo> exportParamConfigVoList,HttpServletResponse response){
        List<Map<String,Object>> mapList = new ArrayList<>();
        if (CollUtil.isNotEmpty(exportParamConfigVoList)) {
            for (ExportParamConfigVo exportParamConfigVo : exportParamConfigVoList) {
                List<GkStationConfigurationVo> stationConfigurations = exportParamConfigVo.getStationConfigurations();
                if (CollUtil.isNotEmpty(stationConfigurations)) {
                    for (GkStationConfigurationVo stationConfiguration : stationConfigurations) {
                        stationConfiguration.setDefaultValue(stationConfiguration.getSaveValue());
                        stationConfiguration.setDisplayName(stationConfiguration.getTempConfigName());
                    }
                    ExportParams exportParams = new ExportParams();
                    exportParams.setSheetName(exportParamConfigVo.getStationName());
                    Map<String, Object> map = new HashMap<>();
                    map.put("title", exportParams);
                    map.put("entity", GkStationConfigurationVo.class);
                    map.put("data", exportParamConfigVo.getStationConfigurations());
                    mapList.add(map);
                }
            }
            List<Long> stationIds = exportParamConfigVoList.stream().map(ExportParamConfigVo::getStationId).collect(Collectors.toList());
            List<GkStation> gkStations = gkStationMapper.selectInfosByIds(stationIds);
            List<Long> productionIds = gkStations.stream().map(GkStation::getProductionLineId).distinct().collect(Collectors.toList());
            List<GkProductionLineVo> gkProductionLineVos = gkProductionLineMapper.selectInfoByIds(productionIds);
            List<String> productionNames = gkProductionLineVos.stream().map(GkProductionLineVo::getName).collect(Collectors.toList());
            String fileName = StringUtils.join(productionNames, "-");
            Workbook workbook = null;
            try {
                workbook = ExcelExportUtil.exportExcel(mapList, ExcelType.HSSF);
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
                response.setHeader("Cache-Control", "No-cache");
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.flushBuffer();
                workbook.write(response.getOutputStream());
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (workbook != null) {
                    try {
                        //强行关流
                        workbook.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
